<?php
/**
 * DsCache 接口
 *
 * @filesource _dscache.class.php
 * @package peck
 * @subpackage _cache
 * @version $id: 0.2, utf8, Mon Dec 14 12:07:01 CST 2009
 * @author LD King <kldscs[at]gmail.com>
 * @copyright Copyleft (D.) 2007 - 2009 MiFunny China Inc.
 * @link http://mifunny.info/
 */
abstract class _DsCache{
    
	/**
	 * 默认的缓存策略
	 *
	 * DSCACHE_LIFE_TIME - life_time: 缓存有效时间(秒), 默认值 900
     *    如果设置为 0 表示缓存总是存在,
	 *
	 * DSCACHE_ENCODING - encoding_key: 编码缓存文件名, 默认为 true
     *    默认使用 md5 编码文件名,
     *    设置为 false 则自动去除 ID 中的字符和空格.
     *
     * DSCACHE_DIR - cache_dir: 缓存目录（必须指定）
	 *    $id字段存在带有目录, 则会在缓存目录下创建子目录, 支持多级目录.
	 *    (建议不要在单目录下放置超过1000个文件)
     *
	 * DSCACHE_UMASK - cache_dir_umask: 创建缓存目录的权限, 默认为 0700
     *
	 * @var array
	 */
	protected $_default_policy = array(
		'life_time'         => 900,
		'encoding_key' => true,
		'cache_dir'         => null,
		'cache_dir_umask'   => 0700,
	);
	
   	/**
	 * 构造函数
	 *
	 * @param 默认的缓存策略 $default_policy
	 */
	public function __construct(array $default_policy = null){
		if (!is_null($default_policy))
			$this->_default_policy = array_merge($this->_default_policy, $default_policy);
	}

    /**
     * 初始化 默认策略
     *
	 * @param 默认的缓存策略 $default_policy
     */    
	public function _init(array $default_policy = null){
		if (!is_null($default_policy)){
            $this->_default_policy = $this->_policy($default_policy);
        }else{
            throw new RuntimeException("Error: Give me my own policy please! (class:".__CLASS__.")");
        }
	}

	/**
     * 写入缓存
     *   缓存时间为0, 永不过期
     *
     * @param string $id 缓存唯一标识ID
     * @param mixed $data 缓存内容
     * @param mixed $expiration 缓存时间,默认 int 900
     */
	abstract function set($id, $data, $expiration=null);
	
	/**
     * 读取缓存，失败或缓存撒失效时返回 false
     *
     * @param string $id 缓存唯一标识ID
     * @param array $policy 配置数组
     *
     * @return mixed
     */
	abstract function get($id, $expiration=null);
	
	/**
	 * 删除指定的缓存
	 *
     * @param string $id 缓存唯一标识ID
     * @param int $delay 删除时间
	 */
	public function remove($id, $delay=0){
		$path = $this->_path($id);
		if (is_file($path)) { unlink($path); }
	}
	
	/**
	 * 删除所有的缓存
	 *
	 * @param int $delay 延时删除
	 */
	public function clean($delay=0){
		_file::rm($this->_default_policy['cache_dir'],true);
	}
	
    /**
     * 确定缓存文件名
     *
     * @param string $id
     * @param array $policy
     *
     * @return string
     */
    protected function _path($id){
    	$path = pathinfo($id);
    	
    	if ( $this->_default_policy['encoding_key'] ){
			$filename = 'DsCache_' . md5( $path['basename'] ) . '.php';
		}else{
			$filename = 'DsCache_' . preg_replace("/[[:punct:]]|[[:space:]]/", '', $path['basename']) . '.php';
		}	
		
        $real_dir = $this->_default_policy['cache_dir']; //$path['dirname'] = trim( $path['dirname'], '\\/');
		$real_dir = _file::check($path['dirname'], $real_dir);
		
        return $real_dir . DIRECTORY_SEPARATOR . $filename;
    }

    /**
     * 返回有效的策略选项
     *
     * @param array $policy
     * @return array
     */
    protected function _policy(array $policy = null){
    	$my_policy = is_null($policy) ? $this->_default_policy : array_merge($this->_default_policy, $policy);
    	if(!is_dir($my_policy['cache_dir']) or !is_writable($my_policy['cache_dir'])){
    		throw new RuntimeException("Please Fix Cache Directory({$my_policy['cache_dir']})!");
    	}else{
    		$my_policy['cache_dir'] = rtrim($my_policy['cache_dir'], '\\/');
    	}
        return $my_policy;
    }

}//END inter DsCache
?>